﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using PmSoft.Core.EventBus;
using PmSoft.Core.Reflection;
using System.Reflection;

namespace PmSoft.Core;

/// <summary>
/// 服务集合扩展方法，用于注册核心服务和自动注入。
/// </summary>
public static class ServiceCollectionExtensions
{
	/// <summary>
	/// 添加核心服务到服务集合中。
	/// </summary>
	/// <param name="services">服务集合。</param>
	/// <param name="configuration">配置对象。</param>
	/// <returns>服务集合。</returns>
	/// <exception cref="ArgumentNullException">当 <paramref name="services"/> 为 null 时抛出。</exception>
	public static IServiceCollection AddCore(this IServiceCollection services, IConfiguration configuration)
	{
		if (services == null) throw new ArgumentNullException(nameof(services));

		// 注册请求上下文
		services.AddScoped<IApplicationContext, ApplicationContext>();

		// 注册本地事件总线
		services.AddSingleton<IEventBus, LocalEventBus>();

		// 自动注册服务
		services.AutoRegister();

		return services;
	}


	/// <summary>
	/// 自动注册所有程序集中的服务。
	/// </summary>
	/// <param name="services">服务集合。</param>
	/// <returns>服务集合。</returns>
	public static IServiceCollection AutoRegister(this IServiceCollection services)
	{
		// 获取所有引用的程序集
		var assemblies = GetAllReferencedAssemblies();
		// 注册每个程序集中的服务和事件处理器
		foreach (var assembly in assemblies)
		{
			//Console.WriteLine(assembly.FullName);
			services.AddEvents(assembly);
			services.AutoRegister(assembly);
		}

		return services;
	}

	/// <summary>
	/// 自动注册指定程序集中的服务。
	/// </summary>
	/// <param name="services">服务集合。</param>
	/// <param name="assembly">要注册的程序集。</param>
	/// <returns>服务集合。</returns>
	public static IServiceCollection AutoRegister(this IServiceCollection services, Assembly assembly)
	{
		foreach (var implementationType in assembly.ExportedTypes.Where(x => x is { IsAbstract: false, IsInterface: false }))
		{
			var typeAccessor = TypeAccessor.Get(implementationType, null);
			var attr = typeAccessor.Context.GetAttribute<InjectAttribute>();
			if (attr != null)
			{
				var serviceTypes = attr.GetTargetTypes();
				var lifetime = attr.Lifetime;

				// 注册实现类型
				services.TryAdd(new ServiceDescriptor(implementationType, implementationType, lifetime));

				// 注册实现的接口
				foreach (var serviceType in serviceTypes)
				{
					services.TryAdd(new ServiceDescriptor(serviceType, implementationType, lifetime));
				}
			}
		}

		return services;
	}
 

	private static HashSet<Assembly> GetAllReferencedAssemblies()
	{
		var assemblies = new HashSet<Assembly>();
		var visited = new HashSet<string>();
		var queue = new Queue<Assembly>();

		var entryAssembly = Assembly.GetEntryAssembly();
		if (entryAssembly != null)
		{
			queue.Enqueue(entryAssembly);
		}

		while (queue.Count > 0)
		{
			var assembly = queue.Dequeue();
			if (!assemblies.Add(assembly)) continue; // 跳过已处理的程序集

			foreach (var reference in assembly.GetReferencedAssemblies())
			{
				if (visited.Add(reference.FullName))
				{
					try
					{
						var refAssembly = Assembly.Load(reference);
						queue.Enqueue(refAssembly);
					}
					catch (Exception)
					{
					}
				}
			}
		}

		return assemblies;
	}

}